#pragma once
#include "RapidXML/rapidxml.hpp"
#include <vector>
#include "Tracer.h"
#include "Sampler.h"
#include "BaseAcc.h"

namespace mray{

struct Collible;
struct BaseObject;
struct BaseLight;
struct AreaLight;
struct BaseMaterial;
struct BaseTexture;
struct Camera;

struct Parser{
	virtual ~Parser();

	//interface to interact with user
	Camera& GetCamera(int camId){ return *(m_camList[camId]); }

	//output
	int							m_width;
	int							m_height;

protected:

	void Parse(const std::string& xmlPath);

	std::vector<BaseObject*>	m_objList;
	std::vector<Camera*>		m_camList;
	std::vector<BaseLight*>		m_ligList;
	std::vector<AreaLight*>		m_areaLigList;
	std::vector<BaseMaterial*>	m_mtlList;
	std::vector<BaseTexture*>	m_texList;

	BaseTexture*				m_pBgTex;
	//params
	BaseTracer*					m_pTracer;
	BaseAcc*					m_pAcc;
	BaseSampler*				m_pAASpl;
	int							m_depth;
	//debug
	int							m_startX, m_startY;
	int							m_areaX, m_areaY;
	bool						m_renderArea;

private:
	void ParseGlobal(rapidxml::xml_node<>* rootNode);
	void ParseSetting(rapidxml::xml_node<>* settingNode);
	void ParseDebug(rapidxml::xml_node<>* debugNode);
	void ParseBackground(rapidxml::xml_node<>* backgroundNode);

	BaseObject*		ParseModel(rapidxml::xml_node<>* modelNode);
	BaseLight*		ParseLight(rapidxml::xml_node<>* lightNode);
	AreaLight*		ParseAreaLight(rapidxml::xml_node<>* areaLightNode);
	Camera*			ParseCamera(rapidxml::xml_node<>* cameraNode);
	BaseMaterial*	ParseMaterial(rapidxml::xml_node<>* materialNode);
	BaseTexture*	ParseTexture(rapidxml::xml_node<>* textureNode);
	BaseSampler*	ParseSampler(rapidxml::xml_node<>* samplerNode);

	bool ParseFloat(rapidxml::xml_node<>* node, char* name, float& f)const;
	bool ParseInt(rapidxml::xml_node<>* node, char* name, int& f)const;
	bool ParseVec3(rapidxml::xml_node<>* node, char* name, vec3& f)const;
	bool ParseBool(rapidxml::xml_node<>* node, char* name, bool& b)const;

};

}